﻿using System;
using Microsoft.Xna.Framework;

namespace Phoenix.Xna.Framework.Input.Mice
{
    /// <summary>
    /// Tracks the state of the mouse scrollwheel, allowing for complex mapping of user input to engine action.
    /// </summary>
    public class MouseScrollWheelMap : InputMap
    {
        /// <summary>
        /// Raised when the position of the mouse scrollwheel changes.
        /// </summary>
        public event EventHandler<InputMapEventArgs<MouseScrollWheelMap>> ValueChanged;

        /// <summary>
        /// Gets the current position of the mouse scrollwheel.
        /// </summary>
        public int CurrentPosition { get { return MouseStateManager.Instance.CurrentScrollWheelValue; } }

        /// <summary>
        /// Gets the previous position of the mouse scrollwheel.
        /// </summary>
        public int PreviousPosition { get { return MouseStateManager.Instance.PreviousScrollWheelValue; } }

        /// <summary>
        /// Gets the current change in position of the mouse scrollwheel.
        /// </summary>
        public int CurrentPositionDelta { get { return MouseStateManager.Instance.CurrentScrollWheelDelta; } }

        /// <summary>
        /// Gets the previous change in position of the mouse scrollwheel.
        /// </summary>
        public int PreviousPositionDelta { get { return MouseStateManager.Instance.PreviousScrollWheelDelta; } }

        /// <summary>
        /// Initializes a new instance of the MouseScrollWheelMap class.
        /// </summary>
        public MouseScrollWheelMap()
        {
            Register();
        }

        /// <summary>
        /// Determines if the current ScrollWheelMap is equal to the specified ScrollWheelMap.
        /// </summary>
        /// <param name="map">The ScrollWheelMap to compare to.</param>
        /// <returns>True if equal, otherwise false.</returns>
        public override bool Equals(object obj)
        {
            if (System.Object.ReferenceEquals(this, obj))
            {
                return true;
            }

            if (obj != null && obj is MouseScrollWheelMap)
            {
                return true;
            }

            return false;
        }

        /// <summary>
        /// Serves as a hash function for the ScrollWheelMap type.
        /// </summary>
        /// <returns>The hash code for this ScrollWheelMap.</returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        /// <summary>
        /// Determines if the left ScrollWheelMap is equal to the right ScrollWheelMap.
        /// </summary>
        /// <param name="left">ScrollWheelMap to the left of the operator.</param>
        /// <param name="right">ScrollWheelMap to the right of the operator.</param>
        /// <returns>True if equal, otherwise false.</returns>
        public static bool operator ==(MouseScrollWheelMap left, MouseScrollWheelMap right)
        {
            if (System.Object.ReferenceEquals(left, right))
            {
                return true;
            }

            if (!System.Object.ReferenceEquals(left, null))
            {
                if (System.Object.ReferenceEquals(right, null))
                {
                    return false;
                }
                else
                {
                    return left.Equals(right);
                }
            }

            return false;
        }

        /// <summary>
        /// Determines if the left ScrollWheelMap is not equal to the right ScrollWheelMap.
        /// </summary>
        /// <param name="left">ScrollWheelMap to the left of the operator.</param>
        /// <param name="right">ScrollWheelMap to the right of the operator.</param>
        /// <returns>True if not equal, otherwise false.</returns>
        public static bool operator !=(MouseScrollWheelMap left, MouseScrollWheelMap right)
        {
            return (left == right) ? false : true;
        }

        private void NotifyEvent(EventHandler<InputMapEventArgs<MouseScrollWheelMap>> eventHandler)
        {
            EventHandler<InputMapEventArgs<MouseScrollWheelMap>> handler = eventHandler;

            if (handler != null)
            {
                handler(this, new InputMapEventArgs<MouseScrollWheelMap>(this));
            }
        }

        #region IInputMap Members

        /// <summary>
        /// Update the IInputMap.
        /// </summary>
        /// <param name="gameTime">A snapshot of the elapsed game time.</param>
        public override void Update(GameTime gameTime)
        {
            if (CurrentPosition != PreviousPosition)
            {
                NotifyEvent(ValueChanged);
            }
        }

        #endregion
    }
}
